package com.le.tester.book.flightjava8.stream;

import cn.hutool.core.util.NumberUtil;
import org.apache.commons.math3.primes.Primes;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.partitioningBy;


/**
 * createTime：2025-06-28 10:18
 * description：
 */
public class Demo {
    public void old7() {
        ArrayList<String> dishList = new ArrayList<>();
        ArrayList<String> lowLenDish = new ArrayList<>();
        for (String item : dishList) {
            if (item.length() < 400) {
                lowLenDish.add(item);
            }
        }
    }

    public void new8() {
//        ArrayList<String> dishList = new ArrayList<>();
//        dishList.stream()
//                .filter()
//                .sorted()
//                .map()
//                .collect()
    }

    public static void main(String[] args) {
        //单个数组+流操作
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        List<Integer> collect = numbers.stream()
                .map(n -> n * n)
                .collect(Collectors.toList());
        System.out.println(collect);

//        多个list的流操作
        List<Integer> numbers1 = Arrays.asList(1, 2, 3);
        List<Integer> numbers2 = Arrays.asList(3, 4);

//        整合成一个二维数组
        List<int[]> pairs = numbers1.stream().flatMap(i -> numbers2.stream().map(j -> new int[]{i, j}))
                .collect(Collectors.toList());
//        要处理多个数组的时候，流中的flapMap是优选，比如交集，并集
        System.out.println(pairs);

        List<int[]> collect1 = numbers1.stream().flatMap(i -> numbers2.stream()
                        .filter(j -> (i + j) % 3 == 0)
                        .map(j -> new int[]{i, j}))
                .collect(Collectors.toList());

        System.out.println(collect1);


        List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
        Optional<Integer> result = someNumbers.stream()
                .map(x -> x * x)
                .filter(x -> x % 3 == 0)
                .findFirst();

        List<Dish> menus = Arrays.asList(new Dish("fish", false, 20, Type.FISH),
                new Dish("meat", false, 10, Type.MEAT));
        menus.stream()
                .mapToInt(Dish::getCalories)
//                默认值给0
                .sum();

        IntStream intStream = IntStream.range(1, 100)
                .filter(n -> n % 2 == 0);
        System.out.println(intStream.count());

//        拼接字符串
        String names = menus.stream().map(Dish::getName).collect(Collectors.joining(","));
        System.out.println(names);

        Optional<Dish> mostCal = menus.stream()
                .reduce((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2);

        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
//        不要这么干，自己写的都懵逼
        integerStream.reduce(new ArrayList<Integer>(), (List<Integer> l, Integer e) -> {
            l.add(e);
            return l;
        }, (List<Integer> l1, List<Integer> l2) -> {
            l1.addAll(l2);
            return l1;
        });
        Map<Type, List<Dish>> dishByType
                = menus.stream().collect(Collectors.groupingBy(Dish::getType));
        System.out.println(dishByType);
//        多级分组
        Map<Type, Map<CaloricLevel, List<Dish>>> mapInner = menus.stream().collect(
                Collectors.groupingBy(Dish::getType, Collectors.groupingBy(
                                dish -> {
                                    if (dish.getCalories() <= 400) return CaloricLevel.DIET;
                                    else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
                                    else return CaloricLevel.FAT;
                                }
                        )
                ));
        System.out.println(mapInner);
//一级map,partitioningBy返回的是一个boole值
        Map<Boolean, List<Dish>> partingMenus
                = menus.stream().collect(partitioningBy(Dish::isVegetarian));
        System.out.println(partingMenus);

//        二级map
        Map<Boolean, Map<Type, List<Dish>>> partingMap2 = menus.stream()
                .collect(partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType)));
        System.out.println(partingMap2);

        List<Integer> numberList = Arrays.asList(1, 3, 5, 7, 9);


    }

    public Map<Boolean, List<Integer>> partitionPrimes(int n) {
        return IntStream.rangeClosed(2, n).boxed()
                .collect(partitioningBy(NumberUtil::isPrimes));

    }

    public boolean isPrime(int candidate) {
        int candidateRoot = (int) Math.sqrt((double) candidate);
        //return takeWhile(Primes)
        return IntStream.rangeClosed(2, candidateRoot).noneMatch(i -> candidate % i == 0);
    }

    public static boolean isPrime(List<Integer> primes, int candidate) {
        return primes.stream().noneMatch(i -> candidate % i == 0);
    }


}
